package org.zjt.demo.config;

import org.springframework.aop.aspectj.AspectJExpressionPointcut;
import org.springframework.aop.aspectj.autoproxy.AspectJAwareAdvisorAutoProxyCreator;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.transaction.PlatformTransactionManager;
import org.springframework.transaction.TransactionDefinition;
import org.springframework.transaction.interceptor.*;


/**
 * @author <a href="juntao.zhang@bkjk.com">juntao.zhang</a>
 * @Description: 利用spring xml得到 aspectj的实现。
 * @Package com.bkjk.platform.druiddemo
 * @date 2018/3/13 14:33
 * @see AspectJAwareAdvisorAutoProxyCreator
 * <p>
 * 生成 bean的代理{@link org.springframework.aop.framework.autoproxy.AbstractAutoProxyCreator#postProcessBeforeInstantiation(Class, String)}
 */
@Configuration
public class AspectConfiguration {

    private static final String EXPRESSION = "execution(* com.bkjk.platform.uc.service..*.*(..))";
    private static final String basePackage = "com.bkjk.platform.uc.service";

    @Bean
    public AspectJExpressionPointcut aspectJExpressionPointcut2() {
        AspectJExpressionPointcut aspectJExpressionPointcut = new AspectJExpressionPointcut();
        aspectJExpressionPointcut.setExpression(EXPRESSION);
        return aspectJExpressionPointcut;
    }

    @Bean
    public TransactionAttributeSource transactionAttributeSource2() {
        NameMatchTransactionAttributeSource methodMapTransactionAttributeSource = new NameMatchTransactionAttributeSource();
        DefaultTransactionAttribute defaultTransactionAttribute = new DefaultTransactionAttribute();
        defaultTransactionAttribute.setPropagationBehavior(TransactionDefinition.PROPAGATION_REQUIRED);
        methodMapTransactionAttributeSource.addTransactionalMethod("save*", defaultTransactionAttribute);
        methodMapTransactionAttributeSource.addTransactionalMethod("insert*", defaultTransactionAttribute);
        methodMapTransactionAttributeSource.addTransactionalMethod("add*", defaultTransactionAttribute);
        methodMapTransactionAttributeSource.addTransactionalMethod("delete*", defaultTransactionAttribute);
        methodMapTransactionAttributeSource.addTransactionalMethod("update*", defaultTransactionAttribute);
        methodMapTransactionAttributeSource.addTransactionalMethod("batch*", defaultTransactionAttribute);
        methodMapTransactionAttributeSource.addTransactionalMethod("do*", defaultTransactionAttribute);
        DefaultTransactionAttribute defaultTransactionAttribute2 = new DefaultTransactionAttribute();
        defaultTransactionAttribute2.setPropagationBehavior(TransactionDefinition.PROPAGATION_SUPPORTS);
        methodMapTransactionAttributeSource.addTransactionalMethod("find*", defaultTransactionAttribute2);
        methodMapTransactionAttributeSource.addTransactionalMethod("select*", defaultTransactionAttribute2);
        return methodMapTransactionAttributeSource;
    }

    @Bean("transactionInterceptor2")
    public TransactionInterceptor transactionInterceptor2(PlatformTransactionManager ptm) {
        TransactionInterceptor interceptor = new TransactionInterceptor();
        interceptor.setTransactionAttributeSource(transactionAttributeSource2());
        interceptor.setTransactionManager(ptm);
        return interceptor;
    }


    @Bean
    public BeanFactoryTransactionAttributeSourceAdvisor transactionAdvisor2(PlatformTransactionManager ptm) {
        BeanFactoryTransactionAttributeSourceAdvisor advisor = new BeanFactoryTransactionAttributeSourceAdvisor();
        advisor.setTransactionAttributeSource(transactionAttributeSource2());
        advisor.setAdvice(transactionInterceptor2(ptm));
        advisor.setClassFilter(aClass -> aClass.getName().contains(basePackage));
        return advisor;
    }


}